package com.ccl.iot.publics;import java.lang.reflect.Constructor;
import java.util.ArrayList;

import android.util.Log;


public abstract class RegisterableClass {
	private static ArrayList<Class<?>> gType = null;
	private static ArrayList<String[]> gConstructor = null;
	
	public static boolean RegisterType(Class<?> aType, String ... aConstructor){
		if (ClassManager.IsSubClass(RegisterableClass.class, aType)){
			if (gType == null){
				gType = new ArrayList<Class<?>>();
			}else if (gType.contains(aType)){
				return true;
			}
			
			if (gType.add(aType)){
				if (gConstructor == null){
					gConstructor = new ArrayList<String[]>();
				}
				
				return gConstructor.add(aConstructor);
			}
		}
		
		return false;
	}
	
	public static int GetType(Class<?> aType){
		if (gType != null){
			return gType.indexOf(aType);
		}else{
			return -1;
		}
	}
	
	public static String[] GetConstructor(int aType){
		if (aType != -1 && gConstructor != null){
			return gConstructor.get(aType);
		}else{
			return null;
		}
	}
	
	public static int CompareContructor(int aType, String ... aConstructor){
		if (aConstructor != null){
			String tConstructor[] = GetConstructor(aType);
			
			if (tConstructor != null && tConstructor.length == aConstructor.length){
				for (int i = 0; i < tConstructor.length; i++){
					if (tConstructor[i].compareToIgnoreCase(aConstructor[i]) != 0){
						return 2;
					}
				}
				
				return 0;
			}else{
				return 1;
			}
		}
		
		return -1;
	}
	
	public static  RegisterableClass Build(int aType, Object ... aParams){
		if (gType != null){
			Class<?> tType = gType.get(aType);
			
			if (tType != null){
				Constructor<?> tConstructor;
				
				if ((tConstructor = ClassManager.FindConstructor(tType, aParams)) != null){
					try {
						return (RegisterableClass) tConstructor.newInstance(aParams);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
		
		return null;
	}
	
	public void sayHi(){
		Log.println(Log.DEBUG, this.getClass().getCanonicalName(), "Hi! I'm " + this.getClass().getCanonicalName());
	}
	
	
	public static class SubClass extends RegisterableClass{
		public static boolean RegisterType(){
			return RegisterType(SubClass.class, "ID", "Name");
		}
		
		public static int GetType(){
			return GetType(SubClass.class);
		}
		
		private int iID = 0;
		private String iName = null;
		
		SubClass(int aID, String aName){
			iID = aID;
			iName = aName;
		}
		
		public void sayHi(){
			super.sayHi();
			
			Log.println(Log.DEBUG, this.getClass().getCanonicalName(), "My ID is " + iID + ", My name is " + iName);
		}
	}
	
	
	public class TestClass{
		public void main(){
			//Register the sub class type first
			int tType;
			
			if (SubClass.RegisterType()){
				//Retrive the sub class type registered
				tType = SubClass.GetType();
				
				if (tType != -1){
					if (CompareContructor(tType, "ID", "Name") == 0){
						RegisterableClass tClass = RegisterableClass.Build(0, 1, "Name");
						
						if (tClass != null){
							tClass.sayHi();
						}
					}
				}
			}
			
		}
	}
}
